package codeflyer.server;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.xml.ws.WebEndpoint;

import org.apache.log4j.Logger;

import codeFlyer.web.api.Filter;
import codeFlyer.web.api.HttpServlet;
import codeFlyer.web.api.HttpSession;
import codeFlyer.web.api.Listener;
import codeflyer.server.classload.ClassLoad;
import codeflyer.server.utils.AnalysisXml;
import codeflyer.server.utils.CountDownUtil;

/**
 * @author CodeFlyer
 * @date Apr 25, 2020
 * @version 1.0
 */

public class ServerStart implements Runnable{
	private static final String projectPath = new File("").getAbsolutePath().replaceAll("\\\\", "/");
	private static Logger logger = Logger.getLogger(ServerStart.class);
	//创建一个线程池
	private static ExecutorService executorService = Executors.newCachedThreadPool();
	private String port = "";
	private String project = "";
	private Map<String, List<HttpServlet>> servletMap = null;  //存储项目的所有servlet对象和路径
	private Map<String, List<Filter>> filterMap = null;       //存储项目的所有filter对象
	private List<Listener> listenerList = null;               //存储项目的所有listener对象
	private Map<String, Session> sessions = new ConcurrentHashMap<String, Session>();  //每个项目所属的session
	private ApplicationContext applicationContext = null;
	private Map<String, Long> timeMap = new ConcurrentHashMap<String, Long>();      //存储每次的初始值
	
	//	private Map<String, String> applicationContext = new HashMap<>();  //每个项目唯一的域
	//把存储session的map放在这里服务器创建的同事进行创建,线程同步的map
	//application对象也在这里创建,服务器创建的同时在这里创建
	//不过这里涉及到多线程同步的问题,这里的map绝对不能使用普通的map
	
	public ServerStart(String port, String project) {
		super();
		this.port = port;
		this.project = project;
	}
	
	

	public ApplicationContext getApplicationContext() {
		return applicationContext;
	}



	public void setApplicationContext(ApplicationContext applicationContext) {
		this.applicationContext = applicationContext;
	}



	public Map<String, List<HttpServlet>> getServletMap() {
		return servletMap;
	}



	public void setServletMap(Map<String, List<HttpServlet>> servletMap) {
		this.servletMap = servletMap;
	}



	public Map<String, List<Filter>> getFilterMap() {
		return filterMap;
	}



	public void setFilterMap(Map<String, List<Filter>> filterMap) {
		this.filterMap = filterMap;
	}



	public List<Listener> getListenerList() {
		return listenerList;
	}



	public void setListenerList(List<Listener> listenerList) {
		this.listenerList = listenerList;
	}



	public void task() {
		try {
			System.out.println("得到的端口号---->"+port);
			//服务器开启了一个监听端口
			ServerSocket serverSocket = new ServerSocket(Integer.valueOf(port));  //使用项目定义的端口号
			logger.debug("服务器启动");
			logger.debug("项目路径--->"+project);
					
			//开启定时任务,只要服务器开启永远按照某个特定频率进行执行
			//每一个ip开启一个线程,进行计时操作,该线程是一个while循环,每次循环获得新的时,即map里的时间,然后比较当前时间,是否超过设定值,超过就break;跳出循环线程结束
			//并且把ip对应Map的key-value删除
			//得到初始时间(从map里面取,ip对应初始时间),
			
			//这里弄个定时任务,每次从socket获取用户的ip然后重新设置初始时间
			while(true) {
				Socket socket = serverSocket.accept();
				//得到ip地址,然后判断有没有创建session
				String ip = socket.getInetAddress().getHostAddress();
				if(sessions.get(ip)!=null) {    //相同ip访问
					//计时清零
					timeMap.put(ip, System.currentTimeMillis());
					System.out.println("有一个ip地址重复访问"+ip);
				}else {
					sessions.put(ip, new Session());
					//新建第一个session并开启计时线程
					new CountDownUtil(sessions,timeMap, ip).executorCountDown();  //根据ip开辟线程进行计数操作
					System.out.println("这个ip地址第一次访问"+ip);
				}
				
			//新的问题来了,每个浏览器都要对应一个session,不管是不是同一个ip,我这里只针对一个浏览器	
				
				//每一次监听一个新的连接就会创建一个线程来处理,无上限
				ServerDispatcher serverDispatcher = new ServerDispatcher(socket);
				serverDispatcher.setFilterMap(filterMap);
				serverDispatcher.setListenerList(listenerList);
				serverDispatcher.setServletMap(servletMap);
				serverDispatcher.setSession(sessions.get(ip));
				serverDispatcher.setApplicationContext(applicationContext);
				serverDispatcher.setProject(project);
				executorService.execute(serverDispatcher);  //60秒该线程不执行就会复用 
			}
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			executorService.shutdown();
		}
	}


	@Override
	public void run() {
		// TODO Auto-generated method stub
		task();
	}
}


